package com.wonders.frame.service;

import com.wonders.frame.common.Commons;
import com.wonders.frame.common.Enum.ChangeType;
import com.wonders.frame.entity.AuthChanges;
import com.wonders.frame.repository.AuthChangesRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
@Transactional
public class AuthChangesService {
    public static int num = 3;//每次最多记录的异动数量
    @Autowired
    private AuthChangesRepository repo;

    /**
     * @param userMap:       登录用户信息
     * @param changeContent: 变更内容
     * @param changeObj:     变更对象
     * @param changeType:    变更类型
     */
    public void setSimpleChanges(Map<String, String> userMap, String changeContent, String changeObj, ChangeType changeType) {
        try {
            AuthChanges changes = new AuthChanges();
            changes.setChangeContent(changeContent);
            changes.setChangeObj(changeObj);
            changes.setChangeType(changeType.toString());
            changes.setOpeUser(userMap.get("userId"));
            changes.setOpeDate(new Date());
            changes.setRemoved(0);
            repo.save(changes);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @param userMap:    登录用户信息
     * @param changeId:   变更对象id
     * @param changeObj:  变更对象
     * @param changeType: 变更类型
     */
    public void setChanges(Map<String, String> userMap, String changeId, String changeObj, ChangeType changeType) {
        AuthChanges changes = new AuthChanges();
        changes.setChangeId(changeId);
        changes.setChangeObj(changeObj);
        changes.setChangeType(changeType.toString());
        changes.setOpeUser("KevinYang");
        changes.setOpeDate(new Date());
        repo.save(changes);
    }

    /**
     * @param userMap:    登录用户信息
     * @param colMap:     字段名映射
     * @param oldObj：     变更前对象
     * @param newObj：     变更后对象
     * @param changeId:   变更对象id
     * @param changeObj:  变更对象
     * @param changeType: 变更类型
     * @param colDicMap:  代码值转换map
     */
    public void setChanges(Map<String, String> userMap, Map<String, String> colMap, Object oldObj, Object newObj,
                           String changeId, String changeObj, ChangeType changeType,
                           Map<String, Map<String, String>> colDicMap) {
        List<String> list = compile(oldObj, newObj, colMap, colDicMap);
        if (list.size() != 0) {
            int cNum = (list.size() - 1) / num;
            System.out.println("cNum:" + cNum);
            for (int i = 0; i <= cNum; i++) {
                StringBuffer str = new StringBuffer("");
                for (int j = 0; j < num; j++) {
                    if (list.size() != 0) {
                        str.append(list.get(0)).append("</br>");
                        list.remove(0);
                    } else {
                        break;
                    }
                }
                AuthChanges changes = new AuthChanges();
                changes.setChangeContent(str.toString());
                changes.setOpeUser("KevinYang2");
                changes.setOpeDate(new Date());
                changes.setChangeId(changeId);
                changes.setChangeObj(changeObj);
                changes.setChangeType(changeType.toString());
                changes.setRemoved(0);
                repo.save(changes);
            }
        }
    }

    @SuppressWarnings("unchecked")
    public static List<String> compile(Object oldObj, Object newObj, Map<String, String> map,
                                       Map<String, Map<String, String>> colDicMap) {
        List<String> list = new ArrayList<>();
        Class<Object> cOldObj = (Class<Object>) oldObj.getClass();
        Field[] filesDb = cOldObj.getDeclaredFields();
        Class<Object> cNewObj = (Class<Object>) newObj.getClass();
        for (Field field : filesDb) {
            String getMethodName = "get"
                    + field.getName().substring(0, 1).toUpperCase()
                    + field.getName().substring(1);
            try {
                Method mOldObj = cOldObj.getMethod(getMethodName);
                Method mNewObj = cNewObj.getMethod(getMethodName);
                try {
                    if (mOldObj != null) {
                        Object valOld = Commons.dealNull(mOldObj.invoke(oldObj));
                        Object valNew = Commons.dealNull(mNewObj.invoke(newObj));
                        if (valOld != null) {
                            if (!valOld.equals(valNew)) {
                                if (null != map.get(field.getName())) {
                                    list.add(Commons.generateContent(field.getName(),
                                            valOld, valNew, map, colDicMap));
                                }
                            }
                        } else if (valNew != null) {
                            if (!valNew.equals(valOld)) {
                                if (null != map.get(field.getName())) {
                                    list.add(Commons.generateContent(field.getName(),
                                            valOld, valNew, map, colDicMap));
                                }
                            }
                        }
                    }
                } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
                    e.printStackTrace();
                }
            } catch (NoSuchMethodException | SecurityException e) {
                e.printStackTrace();
            }
        }
        return list;
    }
}
